package com.symphony.parsing;

import java.io.File;
import java.io.FileInputStream;
import java.io.InputStream;
import java.util.ArrayList;
import java.util.List;

import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;

import org.w3c.dom.Document;
import org.w3c.dom.Node;
import org.w3c.dom.NodeList;
import org.xml.sax.InputSource;

public class DomParser {

	public Document parse(String path) {
		Document doc = null;
		DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
		dbf.setValidating(false);

		try {
			DocumentBuilder db = dbf.newDocumentBuilder();

			InputStream byteStream = readFile(path);
			InputSource is = new InputSource(byteStream);
			doc = db.parse(is);
		} catch (Exception e) {
			e.printStackTrace();
		}

		return doc;
	}
	
	public Content parseNavigation(Document doc) {
		
		NodeList navNodes = doc.getDocumentElement().getChildNodes();
		navNodes = doc.getElementsByTagName("nav");
		return parseNavNodes(navNodes);
	}

	public Content parseNavNodes(NodeList nodes) {
		Content content = null;
		for (int i = 0; i < nodes.getLength(); i++) {
			Node currNode = nodes.item(i);
			String idValue = currNode.getAttributes().getNamedItem("id")
					.getNodeValue();
			if (idValue.equals("toc")) {
				content = parseOlNode(currNode.getChildNodes().item(1));
				break;
			}
		}
		return content;
	}

	public Content parseOlNode(Node olNode) {
		
		Content content = new Content();
		
		NodeList nodes = olNode.getChildNodes();
		for (int i = 0; i < nodes.getLength(); i++) {
			Node currNode = nodes.item(i);
			if(currNode.getNodeName().equals("li")) {
				
				content.addSection(parseLiNode(currNode));
				
			} else if(currNode.getNodeName().equals("ol")) {
			
				Section s = new Section();
				s.setSubcontent(parseOlNode(currNode));
				content.addSection(s);
				
			}
			
		}
		
		return content;
	}
	
	public Section parseLiNode(Node liNode) {
		NodeList nodes = liNode.getChildNodes();
		Section section = new Section();
		
		if(nodes.getLength() > 3) {
			System.out.println("parseLiNode > 1");
			for (int i = 0; i < nodes.getLength(); i++) {
				Node currNode = nodes.item(i);
				if(currNode.getNodeName().equals("ol")) {
					
					section.setSubcontent(parseOlNode(currNode));
					
				}
				
			}

		} else if(nodes.getLength() == 3) {
			Node aNode = nodes.item(1) == null ? nodes.item(0) : nodes.item(1);
			section.setText(aNode.getTextContent());
		}
		
		return section;
	}

	private InputStream readFile(String path) {
		File file = new File(path);
		FileInputStream fis = null;
		try {
			fis = new FileInputStream(file);
		} catch (Exception e) {
			e.printStackTrace();
		}
		return fis;
	}
}

class Content {
	private List<Section> sections = new ArrayList<Section>();
	
	public void addSection(Section s) {
		sections.add(s);
	}
	
	public List<Section> getSections() {
		return sections;
	}
	
	@Override
	public String toString() {
		StringBuilder builder = new StringBuilder();
		
		for(Section s: sections) {
			builder.append(s.toString());
			builder.append("\n");
		}
		
		return builder.toString();
	}
	
}

class Section {
	private String text;
	private Content subContent;
	
	public void setText(String text) {
		this.text = text;
	}
	
	public void setSubcontent(Content subcontent) {
		this.subContent = subcontent;
	}
	
	@Override
	public String toString() {
		StringBuilder builder = new StringBuilder();
		if(text != null)
			builder.append(text);
		
		if(subContent != null) {
			builder.append(subContent.toString());
		}
		
		return builder.toString();
	}
}